package com.neulogistics.contrib.warehouse.domain.service;

import com.neulogistics.contrib.warehouse.domain.exception.WarehouseDomainException;
import com.neulogistics.contrib.warehouse.domain.model.aggregate.CirculationOrder;
import com.neulogistics.contrib.warehouse.domain.model.aggregate.Inventory;
import com.neulogistics.contrib.warehouse.domain.model.aggregate.Warehouse;
import com.neulogistics.contrib.warehouse.domain.model.enumeration.CirculationDetail;
import com.neulogistics.contrib.warehouse.domain.model.enumeration.CirculationType;
import com.neulogistics.contrib.warehouse.domain.model.valueobject.GoodsItem;
import com.neulogistics.contrib.warehouse.domain.repository.ICirculationOrderRepository;
import com.neulogistics.contrib.warehouse.domain.repository.IInventoryRepository;
import com.neulogistics.contrib.warehouse.domain.repository.IWarehouseRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@Service
public class WarehouseDomainService implements IWarehouseDomainService {
    @Resource
    IInventoryRepository inventoryRepository;

    @Resource
    IWarehouseRepository warehouseRepository;

    @Resource
    ICirculationOrderRepository circulationOrderRepository;


    @Override
    public Boolean transferDelivery(Integer centerWarehouseId, Long outboundOrderId,
                                    Integer subWarehouseId, Long inboundOrderId,
                                    Long transferOrderId, GoodsItem goodsItem) throws WarehouseDomainException {
        // 获取库存数据
        Inventory inventory = inventoryRepository.findByWarehouseAndGoods(centerWarehouseId, goodsItem.getGoodsId());

        // 检查库存是否充足
        boolean isAdequate = false;
        isAdequate = inventory.checkInventory(goodsItem.getCount());

        // 不足，返回
        if(!isAdequate){
            return Boolean.FALSE;
        }

        // 充足，分配库存，生成对应出入库单
        inventory.allocateInventory(goodsItem.getCount());

        List<GoodsItem> goodsItems = Arrays.asList(goodsItem);
        // 生成中心库房出库单
        CirculationOrder outboundOrder = new CirculationOrder(outboundOrderId, centerWarehouseId,
                CirculationType.Outbound, CirculationDetail.Transfer_Outbound,
                transferOrderId, goodsItems);
        // 生成分站库房入库单
        CirculationOrder inboundOrder = new CirculationOrder(inboundOrderId, subWarehouseId,
                CirculationType.Inbound, CirculationDetail.Transfer_Inbound,
                transferOrderId, goodsItems);
        // 持久化
        circulationOrderRepository.save(outboundOrder);
        circulationOrderRepository.save(inboundOrder);
        inventoryRepository.save(inventory);

        return Boolean.TRUE;
    }

    @Override
    @Transactional
    public void generateCirculationOrderByDelivery(Integer centerWarehouseId, Long outboundOrderId,
                                                   Integer subWarehouseId, Long inboundOrderId,
                                                   Long transferOrderId, List<GoodsItem> goodsItems) {
        // 生成中心库房出库单
        CirculationOrder outboundOrder = new CirculationOrder(outboundOrderId, centerWarehouseId,
                CirculationType.Outbound, CirculationDetail.Transfer_Outbound,
                transferOrderId, goodsItems);
        // 生成分站库房入库单
        CirculationOrder inboundOrder = new CirculationOrder(inboundOrderId, subWarehouseId,
                CirculationType.Inbound, CirculationDetail.Transfer_Inbound,
                transferOrderId, goodsItems);
        // 持久化
        circulationOrderRepository.save(outboundOrder);
        circulationOrderRepository.save(inboundOrder);
    }

    @Override
    @Transactional
    public void generateCirculationOrderByReturn(Integer centerWarehouseId, Long centerInboundOrderId,
                                                 Integer subWarehouseId, Long subInboundOrderId,
                                                 Long transferOrderId, List<GoodsItem> goodsItems) {
        // 生成分站库房入库单
        CirculationOrder subInboundOrder = new CirculationOrder(subInboundOrderId, subWarehouseId,
                CirculationType.Inbound, CirculationDetail.Return_Inbound,
                transferOrderId, goodsItems);
        // 生成中心库房入库单
        CirculationOrder centerInboundOrder = new CirculationOrder(centerInboundOrderId, centerWarehouseId,
                CirculationType.Inbound, CirculationDetail.Return_Inbound,
                transferOrderId, goodsItems);
        // 持久化
        circulationOrderRepository.save(subInboundOrder);
        circulationOrderRepository.save(centerInboundOrder);
    }
}
